// 模板引擎模块
F.module('lib/template', function() {
	/**
	 * 模板引擎 处理数据域编译模板入口
	 * @param str  模板容器 id 或 模板字符串
	 * @param data 渲染数据
	 */
	var _TplEngine = function(str, data) {
		// 如果数据渲染模板结果
		if (data instanceof Array) {
				// 缓存渲染模板结果
			var html = '',
				// 数据索引
				i = 0,
				// 数据长度
				len = data.length;
			// 遍历数据
			for (; i < len; i++) {
				// 缓存模板渲染结果，也可以写成 html += arguments.callee(str, data[i])
				html += _getTpl(str)(data[i]);
			}
			// 返回模板渲染最终结果
			return html;
		} else {
			// 返回模板渲染结果
			return _getTpl(str)(data);
		}
	},
	/**
	 * 获取模板
	 * @param str 模板容器 id，或者模板字符串
	 */
	_getTpl = function(str) {
		// 获取元素
		var ele = document.getElementById(str);
		// 如果元素存在
		if (ele) {
			// 如果是textarea或input，获取元素value值，否则获取元素内容
			var html = /^(textarea|input)$/i.test(ele.nodeName) ? ele.value : ele.innerHTML;
			return _compileTpl(html);
		} else {
			// 编译模板
			return _compileTpl(str);
		}
	},
	/**
	 * 处理模板
	 * 模板：<a>{%=test%}</a>
	 * 结果：template_push('<a>', typeof(test)==='undefined'?'':test, '</a>');
	 */
	_dealTpl = function(str) {
		var _left = '{%',	// 左分隔符
			_right = '%}';	// 右分隔符
			// 显示转化为字符串
		return String(str)
			// 转义标签内的< 如：<div>{%if(a&lt;b)%}</div> -> <div>{%if(a<b)%}</div>
			.replace(/&lt;/g, '<')
			// 转义标签内的>
			.replace(/&gt;/g, '>')
			// 过滤回车符、制表符、换行符
			.replace(/[\r\t\n]/g, '')
			// 替换内容
			.replace(new RegExp(_left + '=(.*?)' + _right, 'g'), "',typeof($1)==='undefined'?'':$1,'")
			// 替换左分隔符
			.replace(new RegExp(_left, 'g'), "');")
			// 替换右分隔符
			.replace(new RegExp(_right, 'g'), "template_array.push('");
	},
	/**
	 * 编译模板
	 * @param str 模板数据
	 */
	_compileTpl = function(str) {
		var fnBody = `
			// 声明 template_array 模板容器组
			var template_array = [];
			// 闭包，模板容器组添加成员
			(function(data) {
				// 渲染数据变量的执行函数体
				var template_key = '';
				// 遍历渲染数据
				for(key in data) {
					// 为渲染数据变量的执行函数体添加赋值语句
					template_key += ('var ' + key + '=data[\"' + key + '\"];');
				}
				// 执行渲染数据变量函数
				eval(template_key);
				// 为模板容器组添加成员（注意，此时渲染数据将替换容器中的变量）
				template_array.push('${_dealTpl(str)}');
				// 释放渲染数据变量函数
				template_key = null;
			})(templateData);
			// 返回渲染后的模板容器组，并拼接成字符串
			return template_array.join('');`;
		// 编译函数；参数名，方法体
		return new Function("templateData", fnBody);
	};
	// 返回
	return _TplEngine;
});
